﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Practices.ServiceLocation;
using System.Collections.ObjectModel;
using System.Windows.Media;
using System.ComponentModel.Composition;

namespace Dynamic_UI_Framework
{
    public class Layout : ILayout
    {
        public Layout()
        {
            Items.CollectionChanged += (s, e) => {
                UIContext.RaiseVisualModified(this);
            };
        }

        readonly ObservableCollection<IVisual> items = new ObservableCollection<IVisual>();

        public ObservableCollection<IVisual> Items
        {
            get { return items; }
        }

        public string Name
        {
            get;
            set;
        }

        public IVisual Owner
        {
            get;
            set;
        }

        public void Activate(IVisual v)
        {
            if (Owner != null)
                Owner.Activate(this);

        }

        public FrameworkElement Target
        {
            get;
            set;
        }

        public List<MenuItem> GetMenuItem()
        {
            List<MenuItem> list = new List<MenuItem>();
            BenchAdapterMapping mappint = ServiceLocator.Current.GetInstance<BenchAdapterMapping>();
            MenuItem menu = new MenuItem { Header = mappint.Name };
            foreach (var item in mappint.Mappings)
            {
                MenuItem mi = new MenuItem();
                mi.Header = item.Key.Name;
                mi.Tag = item.Value;
                mi.Click += (s, e) =>
                {
                    IAdapter adapter = mi.Tag as IAdapter;
                    if (adapter == null)
                        return;

                    LayoutDialog d = new LayoutDialog();
                    d.ShowDialog();
                    if (d.DialogResult == false)
                        return;

                    if (string.IsNullOrEmpty(d.TargetName))
                        return;
                    UserControl u = new UserControl { Background = Brushes.Yellow };
                    u.Background = d.TargetBackground;
                    u.Width = d.TargetWidth;
                    u.Height = d.TargetHeight;
                    DockPanel.SetDock(u, d.TargetDock);

                    IVisual v = adapter.Initialize(u, d.TargetName) as IVisual;
                    v.Owner = this;
                    this.Items.Add(v);
                };
                menu.Items.Add(mi);
            }

            list.Add(menu);
            return list;
        }
    }

    [Export("Layout", typeof(IBuilder))]
    public class LayoutBuilder : IBuilder
    {
        public UINode GetUINode(IVisual obj)
        {
            Layout layout = obj as Layout;
            if (layout == null)
                return null;

            UINode node = new UINode();
            node.Target = layout;
            node.TypeName = layout.GetType().Name;
            node.Name = layout.Name;
            node.Properties.Add("target", layout.Target.GetType().FullName);

            foreach (var it in layout.Items)
            {
                string key = it.GetType().Name;
                IBuilder builder = ServiceLocator.Current.GetInstance<IBuilder>(key);
                if (builder == null)
                    throw new Exception("builder == null");

                UINode child = builder.GetUINode(it);
                child.Owner = node;
                node.Children.Add(child);
            }
            return node;
        }
        public IVisual Build(UINode node)
        {
            string target = node.Properties.ContainsKey("target") ? node.Properties["target"].ToString() : null;
            if (string.IsNullOrEmpty(target))
                throw new Exception("string.IsNullOrEmpty(typeFullName)");

            LayoutAdapterMapping mapping = ServiceLocator.Current.GetInstance<LayoutAdapterMapping>();
            IAdapter adapter = mapping.GetMappingByTypeFullName(target);
            if (adapter == null)
                throw new Exception("adapter == null");

            Layout layout = adapter.DefaultBuild(node.Name) as Layout;
            foreach (var item in node.Children)
            {
                IBuilder builder = ServiceLocator.Current.GetInstance<IBuilder>(item.TypeName);
                IVisual child = builder.Build(item) as IVisual;
                child.Owner = layout;
                layout.Items.Add(child);
            }
            return layout;
        }
    }

}
